package com.ncmmall.mall.controller.business.member;

import com.ncmmall.application.business.member.MemberApplication;
import com.ncmmall.application.securitys.logs.OperationLogApplication;
import com.feijin.commons.excel.ExcelExports;
import com.feijin.commons.exceptions.IllegalRequestException;
import com.feijin.commons.lang.Dates;
import com.feijin.commons.securitys.MD5HashUtils;
import com.feijin.commons.webs.Webs;
import com.ncmmall.domain.business.order.Order;
import com.ncmmall.domain.security.user.QWebUser;
import com.ncmmall.domain.security.user.WebUser;
import com.ncmmall.mall.controller.securitys.shiro.Securitys;
import com.ncmmall.mall.params.PageParams;
import com.ncmmall.querychannel.QueryPage;
import com.ncmmall.querychannel.QueryPageRequest;
import com.ncmmall.querychannel.service.QueryChannelService;
import com.google.common.base.Function;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.primitives.Longs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author linxs
 * @Description: 会员管理
 * @Date: 2019-06-26 20:24
 */
@Controller
@RequestMapping(value = "/mall/member")
public class MemberController {

    private final static Logger logger = LoggerFactory.getLogger(MemberController.class);

    @Value("${web.domain}")
    private String webDomain;

    @Autowired
    private QueryChannelService queryChannelService;

    @Autowired
    private MemberApplication memberApplication;

    @Autowired
    private OperationLogApplication logApplication;


    /**
     * 分页条件筛选
     *
     * @param model
     * @param pageParams
     * @param member
     * @return
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    private String list(Model model, PageParams pageParams, WebUser member) {
        QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageParams.getPageNo());
        Map<String, Object> params = Maps.newHashMap();
        String hql = builderSQL("select u from WebUser u where u.role.name = 'MEMBER' ", params, member);
        QueryPage<WebUser> page = queryChannelService.findPage(hql, pageRequest.setParams(params), WebUser.class);
        model.addAttribute("page", page).addAttribute("params", member);

        return "mall/member/list";
    }

    /**
     * 导出Excel
     *
     * @param request
     * @param response
     * @param member
     */
    @RequestMapping(value = "/exports", method = RequestMethod.GET)
    private void exports(HttpServletRequest request, HttpServletResponse response, WebUser member) {
        Map<String, Object> params = Maps.newHashMap();
        String sql = "select u from WebUser u where u.role.name = 'MEMBER' ";
        String hql = builderSQL(sql, params, member);

        List<WebUser> result = queryChannelService.findAll(hql, params, WebUser.class);

        Map<String, Object> data = ImmutableMap.of("result", result);
        ExcelExports document = new ExcelExports.Templates().formTemplate("members.ftl").bind(data).store("members.xls").build();

        try {
            document.generate();
            Webs.download(request, response, document.getFile(), "会员名单" + Dates.transDateToStr(new Date()) + ".xls");

        } catch (Exception e) {
            logger.error("[导出异常]", e);
        }
    }


    /**
     * 重置会员密码 123456
     *
     * @param requestWith
     * @return
     */
    @RequestMapping(value = "/resetPassword", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> resetPassword(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, WebUser params) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            WebUser member = queryChannelService.findOne(QWebUser.webUser.id.eq(params.getId()), WebUser.class);

            memberApplication.modifyPassword(member, MD5HashUtils.MD5("123456"));

            logApplication.eventOfSystem(Securitys.currentUser(), "重置会员密码" + member.getUsername(), Securitys.getIp(request));

            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            logger.error("[重置会员密码异常]", e);
            return ImmutableMap.of("status", false);
        }
    }

//    public static final void main(String[] args) {
//
//        String passwordAsMd5 = MD5HashUtils.asMD5(MD5HashUtils.MD5("123456"), "19907979316");
//        System.out.println(passwordAsMd5);
//    }

    /**
     * 查看会员详情
     *
     * @param model
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/detail", method = RequestMethod.GET)
    private String detail(Model model, @PathVariable("id") long id) {

        WebUser member = queryChannelService.findOne(QWebUser.webUser.id.eq(id), WebUser.class);
        model.addAttribute("member", member);

        return "mall/member/detail";
    }

    /**
     * 会员订单
     *
     * @param model
     * @param pageParams
     * @param order
     * @return
     */
    @RequestMapping(value = "/{id}/orders", method = RequestMethod.GET)
    private String list(Model model, @PathVariable("id") long id, PageParams pageParams, Order order) {

        QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageParams.getPageNo());
        Map<String, Object> params = Maps.newHashMap();
        params.put("id", id) ;
        String hql = builderOrderSQL("select u from Order u where u.member.id = :id ", params, order);
        QueryPage<Order> page = queryChannelService.findPage(hql, pageRequest.setParams(params), Order.class);

        double payAmount = queryChannelService.selectSum("select ifnull(sum(o.price),0) from mall_order o where o.payStatus = 1 and o.member_id = :id ", ImmutableMap.of("id", id));
        double refundAmount = queryChannelService.selectSum("select ifnull(sum(o.price),0) from mall_order o where o.isAfterSale = 1 and o.member_id = :id ", ImmutableMap.of("id", id));

        model.addAttribute("page", page)
                .addAttribute("params", order)
                .addAttribute("payAmount", payAmount)
                .addAttribute("id", id)
                .addAttribute("refundAmount", refundAmount);

        return "mall/member/order/list";
    }

    private String builderOrderSQL(String sql, Map<String, Object> params, Order order) {

        if (order.getStatus() > 0) {
            sql += " and u.status = :status ";
            params.put("status", order.getStatus());
        }

        if (!Strings.isNullOrEmpty(order.getOrderNo())) {
            sql += " and u.orderNo like :orderno ";
            params.put("orderno", "%" + order.getOrderNo() + "%");
        }

        if (order.getPayStatus() > 0) {
            sql += " and u.payStatus = :pstatus ";
            params.put("pstatus", order.getPayStatus());
        }

        if (!Strings.isNullOrEmpty(order.getOrderByCreateTime())) {
            sql += " order by u.createTime " + order.getOrderByCreateTime();
        }

        if (!Strings.isNullOrEmpty(order.getOrderByPrice())) {
            sql += " order by u.price " + order.getOrderByPrice();
        }

        if (!sql.contains("order by")) {
            sql += " order by u.createTime desc ";
        }

        return sql;
    }


    /**
     * 禁用
     *
     * @param requestWith
     * @param id
     * @return
     */
    @RequestMapping(value = "/disable", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> disable(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("id") long id) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            WebUser member = queryChannelService.findOne(QWebUser.webUser.id.eq(id), WebUser.class);
            memberApplication.disable(member);
            logApplication.eventOfSystem(Securitys.currentUser(), "禁止会员登录" + member.getUsername(), Securitys.getIp(request));
            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            logger.error("[锁定会员异常]", e);
            return ImmutableMap.of("status", false);
        }
    }


    /**
     * 启用
     *
     * @param requestWith
     * @param id
     * @return
     */
    @RequestMapping(value = "/enabled", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> enabled(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("id") long id) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            WebUser member = queryChannelService.findOne(QWebUser.webUser.id.eq(id), WebUser.class);
            memberApplication.enabled(member);
            logApplication.eventOfSystem(Securitys.currentUser(), "解锁会员登录" + member.getUsername(), Securitys.getIp(request));
            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            logger.error("[锁定会员异常]", e);
            return ImmutableMap.of("status", false);
        }
    }

    /**
     * 批量禁用
     *
     * @param requestWith
     * @param id
     * @return
     */
    @RequestMapping(value = "/disables", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> disables(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("ids") String data) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            List<String> ids = Splitter.on(";").omitEmptyStrings().trimResults().splitToList(data);

            memberApplication.disables(Lists.transform(ids, new Function<String, WebUser>() {
                @Nullable
                @Override
                public WebUser apply(@Nullable String input) {
                    WebUser member = queryChannelService.findOne(QWebUser.webUser.id.eq(Longs.tryParse(input)), WebUser.class);
                    return member;
                }
            }));

            logApplication.eventOfSystem(Securitys.currentUser(), "批量禁止会员登录", Securitys.getIp(request));

            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            logger.error("[禁用会员异常]", e);
            return ImmutableMap.of("status", false);
        }
    }

    /**
     * 批量启用
     *
     * @param requestWith
     * @param id
     * @return
     */
    @RequestMapping(value = "/enables", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> enables(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("ids") String data) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            List<String> ids = Splitter.on(";").omitEmptyStrings().trimResults().splitToList(data);

            memberApplication.enables(Lists.transform(ids, new Function<String, WebUser>() {
                @Nullable
                @Override
                public WebUser apply(@Nullable String input) {
                    WebUser member = queryChannelService.findOne(QWebUser.webUser.id.eq(Longs.tryParse(input)), WebUser.class);
                    return member;
                }
            }));

            logApplication.eventOfSystem(Securitys.currentUser(), "批量启动会员登录", Securitys.getIp(request));

            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            logger.error("[启用会员异常]", e);
            return ImmutableMap.of("status", false);
        }
    }


    /**
     * 条件查询
     *
     * @param sql
     * @param params
     * @param member
     * @return
     */
    private String builderSQL(String sql, Map<String, Object> params, WebUser member) {

        if (!Strings.isNullOrEmpty(member.getRealName())) {
            sql += " and u.realName like :realname ";
            params.put("realname", "%" + member.getRealName() + "%");
        }

        if (!Strings.isNullOrEmpty(member.getUsername())) {
            sql += " and u.username like :username ";
            params.put("username", "%" + member.getUsername() + "%");
        }

        if (!Strings.isNullOrEmpty(member.getMobile())) {
            sql += " and u.mobile like :mobile ";
            params.put("mobile", "%" + member.getMobile() + "%");
        }

        if (!Strings.isNullOrEmpty(member.getNickname())) {
            sql += " and u.nickname like :nickname ";
            params.put("nickname", "%" + member.getNickname() + "%");
        }

        boolean isDefaultOrder = true;

        if (!Strings.isNullOrEmpty(member.getOrderByCreateTime())) {
            sql += " order by u.createTime " + member.getOrderByCreateTime();
            isDefaultOrder = false;
        }

        if (isDefaultOrder) {
            sql += " order by u.createTime desc ";
        }

        return sql;
    }


}
